package com.infore.siteManagement.dao.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.infore.siteManagement.conf.LowerAliasToBeanResultTransformer;
import com.infore.siteManagement.dao.IEntityManagerDao;
import com.infore.siteManagement.util.Page;

/**
 * 基础查询数据层接口实现类
 * 
 * @author qiye
 * @date 2018年7月10日 下午7:12:31
 */
@Repository
public class EntityManagerDaoImpl implements IEntityManagerDao {

	@Autowired
	EntityManager entityManager;

	@Override
	public <T> T insert(T t) {
		return null;
	}

	@SuppressWarnings("unchecked")
	public List<Object[]> findListByJPQL(String jpql, Object... objects) {
		Query query = entityManager.createQuery(jpql);
		for (int i = 0; i < objects.length; i++) {
			query.setParameter(i + 1, objects[i]);
		}
		List<Object[]> list = query.getResultList();
		entityManager.close();
		return list;
	}

	@SuppressWarnings("unchecked")
	public List<Object[]> findListByJPQL(String jpql, Map<String, Object> map) {
		Query query = entityManager.createQuery(jpql);
		Set<String> set = map.keySet();
		for (String key : set) {
			query.setParameter(key, map.get(key));
		}
		List<Object[]> list = query.getResultList();
		entityManager.close();
		return list;
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> findByJPQL(String jpql, Class<T> clazz, Object... objects) {
		Query query = entityManager.createQuery(jpql, clazz);
		for (int i = 0; i < objects.length; i++) {
			query.setParameter(i + 1, objects[i]);
		}
		List<T> list = query.getResultList();
		entityManager.close();
		return list;
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> findByJPQL(String jpql, Class<T> clazz, Map<String, Object> map) {
		Query query = entityManager.createQuery(jpql, clazz);
		Set<String> set = map.keySet();
		for (String key : set) {
			query.setParameter(key, map.get(key));
		}
		List<T> list = query.getResultList();
		entityManager.close();
		return list;
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> findByJPQL(String jpql, int pageNum, int pageSize, Class<T> clazz, Object... objects) {
		if (pageNum < 1) {
			pageNum = 1;
		}
		if (pageSize < 1) {
			pageSize = 10;
		}
		Query query = entityManager.createQuery(jpql, clazz);
		for (int i = 0; i < objects.length; i++) {
			query.setParameter(i + 1, objects[i]);
		}
		query.setFirstResult((pageNum - 1) * pageSize);
		query.setMaxResults(pageSize);
		List<T> list = query.getResultList();
		entityManager.close();
		return list;
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> findByJPQL(String jpql, int pageNum, int pageSize, Class<T> clazz, Map<String, Object> map) {
		if (pageNum < 1) {
			pageNum = 1;
		}
		if (pageSize < 1) {
			pageSize = 10;
		}
		Query query = entityManager.createQuery(jpql, clazz);
		Set<String> set = map.keySet();
		for (String key : set) {
			query.setParameter(key, map.get(key));
		}
		query.setFirstResult((pageNum - 1) * pageSize);
		query.setMaxResults(pageSize);
		List<T> list = query.getResultList();
		entityManager.close();
		return list;
	}

	@SuppressWarnings("unchecked")
	public <T> Page<T> findPageByJPQL(String jpql, int pageNum, int pageSize, Class<T> clazz, Object... objects) {
		if (pageNum < 1) {
			pageNum = 1;
		}
		if (pageSize < 1) {
			pageSize = 10;
		}
		Query query = entityManager.createQuery(jpql, clazz);
		for (int i = 0; i < objects.length; i++) {
			query.setParameter(i + 1, objects[i]);
		}
		query.setFirstResult((pageNum - 1) * pageSize);
		query.setMaxResults(pageSize);
		List<T> list = query.getResultList();
		// 拼接查询数量jpql
		StringBuilder cb = new StringBuilder();
		cb.append("select count(1) ");
		cb.append(jpql.substring(jpql.indexOf(" from ")));
		// 执行查询数量
		Integer count = Integer.valueOf(findCount(cb.toString(), objects).toString());
		Page<T> page = new Page<T>();
		page.setPageNo(pageNum);
		page.setPageSize(pageSize);
		page.setTotalRecords(count);
		page.setList(list);
		entityManager.close();
		return page;
	}

	@SuppressWarnings("unchecked")
	public <T> Page<T> findPageByJPQL(String jpql, int pageNum, int pageSize, Class<T> clazz, Map<String, Object> map) {
		if (pageNum < 1) {
			pageNum = 1;
		}
		if (pageSize < 1) {
			pageSize = 10;
		}
		System.out.println(jpql);
		Query query = entityManager.createQuery(jpql, clazz);
		Set<String> set = map.keySet();
		for (String key : set) {
			query.setParameter(key, map.get(key));
		}
		query.setFirstResult((pageNum - 1) * pageSize);
		query.setMaxResults(pageSize);
		List<T> list = query.getResultList();
		if (list.size() == 0) {
			list = new ArrayList<T>();
		}
		// 拼接查询数量jpql
		StringBuilder cb = new StringBuilder();
		cb.append("select count(1) ");
		cb.append(jpql.substring(jpql.indexOf(" from ")));
		// 执行查询数量
		Integer count = Integer.valueOf(findCount(cb.toString(), map).toString());
		Page<T> page = new Page<T>();
		page.setPageNo(pageNum);
		page.setPageSize(pageSize);
		page.setTotalRecords(count);
		page.setList(list);
		entityManager.close();
		return page;
	}

	public Object findCount(String jpql, Object... objects) {
		Query query = entityManager.createQuery(jpql);
		for (int i = 0; i < objects.length; i++) {
			query.setParameter(i + 1, objects[i]);
		}
		Object object = query.getSingleResult();
		entityManager.close();
		return object;
	}

	public Object findCount(String jpql, Map<String, Object> map) {
		Query query = entityManager.createQuery(jpql);
		Set<String> set = map.keySet();
		for (String key : set) {
			query.setParameter(key, map.get(key));
		}
		Object object = query.getSingleResult();
		entityManager.close();
		return object;
	}

	@SuppressWarnings("unchecked")
	public <T> T findOneByJPQL(String jpql, Class<T> clazz, Object... objects) {
		Query query = entityManager.createQuery(jpql, clazz);
		for (int i = 0; i < objects.length; i++) {
			query.setParameter(i + 1, objects[i]);
		}
		T t = (T) query.getSingleResult();
		entityManager.close();
		return t;
	}

	@SuppressWarnings("unchecked")
	public <T> T findOneByJPQL(String jpql, Class<T> clazz, Map<String, Object> map) {
		Query query = entityManager.createQuery(jpql, clazz);
		Set<String> set = map.keySet();
		for (String key : set) {
			query.setParameter(key, map.get(key));
		}
		T t = (T) query.getSingleResult();
		entityManager.close();
		return t;
	}

	@Override
	@SuppressWarnings("unchecked")
	public <T> List<T> findBySQL(String sql, Class<T> clazz, Object... objects) {
		Query query = entityManager.createNativeQuery(sql, clazz);
		for (int i = 0; i < objects.length; i++) {
			query.setParameter(i + 1, objects[i]);
		}
		List<T> list = query.getResultList();
		entityManager.close();
		return list;
	}

	@Override
	@SuppressWarnings("unchecked")
	public <T> List<T> findBySQL(String sql, Class<T> clazz, Map<String, Object> map) {
		Query query = entityManager.createNativeQuery(sql, clazz);
		Set<String> set = map.keySet();
		for (String key : set) {
			query.setParameter(key, map.get(key));
		}
		List<T> list = query.getResultList();
		entityManager.close();
		return list;
	}

	@SuppressWarnings("unchecked")
	public <T> Page<T> findPageBySQL(String sql, int pageNum, int pageSize, Class<T> clazz, Object... objects) {
		if (pageNum < 1) {
			pageNum = 1;
		}
		if (pageSize < 1) {
			pageSize = 10;
		}
		Query query = entityManager.createNativeQuery(sql, clazz);
		for (int i = 0; i < objects.length; i++) {
			query.setParameter(i + 1, objects[i]);
		}
		query.setFirstResult((pageNum - 1) * pageSize);
		query.setMaxResults(pageSize);
		List<T> list = query.getResultList();
		// 拼接查询数量jpql
		StringBuilder cb = new StringBuilder();
		cb.append("select count(1) ");
		cb.append(sql.substring(sql.indexOf(" from ")));
		// 执行查询数量
		Integer count = Integer.valueOf(findCount(cb.toString(), objects).toString());
		Page<T> page = new Page<T>();
		page.setPageNo(pageNum);
		page.setPageSize(pageSize);
		page.setTotalRecords(count);
		page.setList(list);
		entityManager.close();
		return page;
	}

	@SuppressWarnings("unchecked")
	public <T> Page<T> findPageBySQL(String sql, int pageNum, int pageSize, Class<T> clazz, Map<String, Object> map) {
		if (pageNum < 1) {
			pageNum = 1;
		}
		if (pageSize < 1) {
			pageSize = 10;
		}
		Query query = entityManager.createNativeQuery(sql, clazz);
		Set<String> set = map.keySet();
		for (String key : set) {
			query.setParameter(key, map.get(key));
		}
		query.setFirstResult((pageNum - 1) * pageSize);
		query.setMaxResults(pageSize);
		List<T> list = query.getResultList();
		// 拼接查询数量jpql
		StringBuilder cb = new StringBuilder();
		cb.append("select count(1) ");
		cb.append(sql.substring(sql.indexOf(" from ")));
		// 执行查询数量
		Integer count = Integer.valueOf(findCount(cb.toString(), map).toString());
		Page<T> page = new Page<T>();
		page.setPageNo(pageNum);
		page.setPageSize(pageSize);
		page.setTotalRecords(count);
		page.setList(list);
		entityManager.close();
		return page;
	}

	@SuppressWarnings("unchecked")
	public List<Object[]> findBySQL(String sql, Object... objects) {
		Query query = entityManager.createNativeQuery(sql);
		for (int i = 0; i < objects.length; i++) {
			query.setParameter(i + 1, objects[i]);
		}
		List<Object[]> list = query.getResultList();
		entityManager.close();
		return list;
	}

	@SuppressWarnings("unchecked")
	public List<Object[]> findBySQL(String sql, Map<String, Object> map) {
		Query query = entityManager.createNativeQuery(sql);
		Set<String> set = map.keySet();
		for (String key : set) {
			query.setParameter(key, map.get(key));
		}
		List<Object[]> list = query.getResultList();
		entityManager.close();
		return list;
	}

	@SuppressWarnings("unchecked")
	public List<Object[]> findPageBySQL(String sql, int pageNum, int pageSize, Map<String, Object> map) {
		if (pageNum < 1) {
			pageNum = 1;
		}
		if (pageSize < 1) {
			pageSize = 10;
		}
		Query query = entityManager.createNativeQuery(sql);
		Set<String> set = map.keySet();
		for (String key : set) {
			query.setParameter(key, map.get(key));
		}
		query.setFirstResult((pageNum - 1) * pageSize);
		query.setMaxResults(pageSize);
		List<Object[]> list = query.getResultList();
		entityManager.close();
		return list;
	}

	@SuppressWarnings("unchecked")
	public List<Object[]> findPageBySQL(String sql, int pageNum, int pageSize, Object... objects) {
		if (pageNum < 1) {
			pageNum = 1;
		}
		if (pageSize < 1) {
			pageSize = 10;
		}
		Query query = entityManager.createNativeQuery(sql);
		for (int i = 0; i < objects.length; i++) {
			query.setParameter(i + 1, objects[i]);
		}
		query.setFirstResult((pageNum - 1) * pageSize);
		query.setMaxResults(pageSize);
		List<Object[]> list = query.getResultList();
		entityManager.close();
		return list;
	}

	public Object findCountBySql(String sql, Map<String, Object> map) {
		Query query = entityManager.createNativeQuery(sql);
		Set<String> set = map.keySet();
		for (String key : set) {
			query.setParameter(key, map.get(key));
		}
		Object object = query.getSingleResult();
		entityManager.close();
		return object;
	}

	public Object findCountBySql(String sql, Object... objects) {
		Query query = entityManager.createNativeQuery(sql);
		for (int i = 0; i < objects.length; i++) {
			query.setParameter(i + 1, objects[i]);
		}
		Object object = query.getSingleResult();
		entityManager.close();
		return object;
	}

	@SuppressWarnings("unchecked")
	public List<Map<String, Object>> getListMapBySQL(String sql) {
		// sql = sql.toUpperCase();
		Query query = entityManager.createNativeQuery(sql);
		query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		// .setResultTransformer(new LowerAliasToBeanResultTransformer(String.class));
		List<Map<String, Object>> list = query.getResultList();
		return list;
	}

	/** 不传参数分页查询 **/
	@SuppressWarnings("unchecked")
	public Page<Map<String, Object>> findPageBySQL(String sql, int pageNum, int pageSize) {
		if (pageNum < 1) {
			pageNum = 1;
		}
		if (pageSize < 1) {
			pageSize = 10;
		}
		Query query = entityManager.createNativeQuery(sql);
		query.setFirstResult((pageNum - 1) * pageSize);
		query.setMaxResults(pageSize);
		query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		List<Map<String, Object>> list = query.getResultList();
		// 拼接查询数量jpql
		StringBuilder cb = new StringBuilder();
		cb.append("select count(1) ");
		if (sql.contains(" FROM ")) {
			cb.append(sql.substring(sql.indexOf(" FROM ")));
		} else {
			cb.append(sql.substring(sql.indexOf(" from ")));
		}
		Query queryCount = entityManager.createNativeQuery(cb.toString());
		// 执行查询数量
		Integer count = Integer.valueOf(queryCount.getSingleResult().toString());
		Page<Map<String, Object>> page = new Page<Map<String, Object>>();
		page.setPageNo(pageNum);
		page.setPageSize(pageSize);
		page.setTotalRecords(count);
		page.setList(list);
		entityManager.close();
		return page;
	}

}
